use super::super::value::{Value, ValueData};
use super::super::method::{Method, MethodType};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;

/// 元组类型的实现
pub struct Tuple;

impl Tuple {
    /// 创建元组值
    pub fn create(elements: Vec<Value>) -> Value {
        let mut methods = HashMap::new();
        
        // 查询方法
        methods.insert(
            "长度".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let ValueData::Tuple(elements) = &args[0].data {
                    Ok(Value::number(elements.len() as f64))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "空否".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let ValueData::Tuple(elements) = &args[0].data {
                    Ok(Value::boolean(elements.is_empty()))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "获取".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let (ValueData::Tuple(elements), ValueData::Number(index)) = 
                    (&args[0].data, &args[1].data)
                {
                    let len = elements.len();
                    let idx = Self::normalize_index(*index as isize, len);
                    if idx < 0 || idx >= len as isize {
                        Err("索引越界".to_string())
                    } else {
                        Ok(elements[idx as usize].clone())
                    }
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "首".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let ValueData::Tuple(elements) = &args[0].data {
                    if elements.is_empty() {
                        Err("元组为空".to_string())
                    } else {
                        Ok(elements[0].clone())
                    }
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "尾".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let ValueData::Tuple(elements) = &args[0].data {
                    if elements.is_empty() {
                        Err("元组为空".to_string())
                    } else {
                        Ok(elements.last().unwrap().clone())
                    }
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "包含".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let (ValueData::Tuple(elements), elem) = (&args[0].data, &args[1]) {
                    let contains = elements.contains(elem);
                    Ok(Value::boolean(contains))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "索引".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let (ValueData::Tuple(elements), elem) = (&args[0].data, &args[1]) {
                    if let Some(index) = elements.iter().position(|x| x == elem) {
                        Ok(Value::number(index as f64))
                    } else {
                        Ok(Value::number(-1.0))
                    }
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "计数".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let (ValueData::Tuple(elements), elem) = (&args[0].data, &args[1]) {
                    let count = elements.iter().filter(|x| *x == elem).count();
                    Ok(Value::number(count as f64))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        // 转换方法
        methods.insert(
            "切片".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let (ValueData::Tuple(elements), ValueData::Number(start), ValueData::Number(end)) = 
                    (&args[0].data, &args[1].data, &args[2].data)
                {
                    let len = elements.len();
                    let start_idx = Self::normalize_index(*start as isize, len);
                    let end_idx = Self::normalize_index(*end as isize, len);
                    
                    if start_idx < 0 {
                        return Err("起始索引越界".to_string());
                    }
                    
                    let start_idx = start_idx as usize;
                    let end_idx = end_idx as usize;
                    
                    if end_idx > len {
                        return Err("结束索引越界".to_string());
                    }
                    
                    if start_idx > end_idx {
                        return Ok(Value::tuple(vec![]));
                    }
                    
                    let sliced: Vec<Value> = elements[start_idx..end_idx].iter().cloned().collect();
                    Ok(Value::tuple(sliced))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "连接".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let (ValueData::Tuple(elements1), ValueData::Tuple(elements2)) = 
                    (&args[0].data, &args[1].data)
                {
                    let mut new_elements = elements1.clone();
                    new_elements.extend(elements2.iter().cloned());
                    Ok(Value::tuple(new_elements))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "转列表".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let ValueData::Tuple(elements) = &args[0].data {
                    Ok(Value::list(elements.clone()))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        methods.insert(
            "转汇".to_string(),
            Method::native(MethodType::Tuple, |args| {
                if let ValueData::Tuple(elements) = &args[0].data {
                    Ok(Value::set(elements.clone()))
                } else {
                    Err("不是元组类型".to_string())
                }
            }),
        );
        
        // 添加通用方法
        super::super::value::Value::add_common_methods(&mut methods, "组");
        
        Value {
            type_name: "组".to_string(),
            data: ValueData::Tuple(elements),
            methods: Rc::new(RefCell::new(methods)),
        }
    }
    
    /// 规范化索引，支持负索引
    fn normalize_index(index: isize, len: usize) -> isize {
        if index < 0 {
            (len as isize) + index
        } else {
            index
        }
    }
}
